﻿using UnityEngine;
using System.Collections.Generic;
using System.Collections;

public class CandyCheckMatch : MonoBehaviour {
    public static CandyCheckMatch instance;
    private GameManager manager;
    public List<GameObject> h_list, v_list;
    [SerializeField]
    private GameObject no_more,sugarCrush,levelCompete;
    [SerializeField]
    private tk2dTextMesh playerScoreN,playerScoreR;
    private bool sugar_crush;
    void Awake(){
        instance = this;
    }
    void Start(){
        sugar_crush = false;
        manager = GameManager.getInstance();
        h_list = new List<GameObject>();
        v_list = new List<GameObject>();
    }
	void Update(){
		if(manager.gamestate==GameState.dropping){
			if(IsArrive()){
				manager.gamestate=GameState.checkaterdrop;
				CandyDrop.instance.CheckPositionObjects();
				CancelInvoke();
				Invoke("CheckAfterDrop",0.7f);
			}
			CandyDrop.instance.CheckCandyIsOverTheBar();
		}
	}
	int count=0;
	private bool IsArrive(){
		for(int i=0;i<CandyDemo.instance.level.GetCandy().Length;i++){
			if(CandyDemo.instance.level.GetCandy()[i].transform.position.y<CandyDrop.instance.bar.transform.position.y){
				count++;
			}
		}
		if(count==CandyDemo.instance.level.GetCandy().Length){
			count=0;
			return true;
		}
		count=0;
		return false;
	}
    public void Check(){	
		if(manager.gamestate!=GameState.checking){return;}
        CandyMatchedConditions.instance.candy_list_matched.Clear();
        if (CandyNeighbor.instance.clicked_candy_ == null) { return; }
        SpecialCheck.instance.MatchCandyCondition();
    }
    public string[] direction = { "up", "down", "left", "right" };
    public void CheckBoardState(){	
		if(Player.instance!=null){
			Player.instance.CancelInvoke();
		}
		if(manager.gamestate!=GameState.checkboardstate){return;}
		no_more.SetActive(false);
		manager.NoMove=false;
		if(manager.IsDestroySpecialMatch){return;}
        CandyDemo.instance.is_show_hint = false;
        for (int i = 0; i < CandyDemo.instance.level.GetCandy().Length; i++){
            for (int j = 0; j < direction.Length; j++){
                if (TestWithNeighbor(CandyDemo.instance.level.GetCandy()[i], direction[j])){
                    CandyDemo.instance.suggest_item1 = CandyDemo.instance.level.GetCandy()[i];
					CandyDemo.instance.suggest_item2 = CandyDemo.instance.level.GetCandy()[i].GetComponent<CandyController>().GetNeighbor(direction[j]);
					manager.Direction=CandyDemo.instance.suggest_item1.GetComponent<CandyController>().GetDirectionNeighbor(CandyDemo.instance.suggest_item2);
					CandyDemo.instance.Hint();
					manager.gamestate=GameState.playing;
					return;
                }
				if ((CandyDemo.instance.level.GetCandy()[i].GetComponent<CandyController>().Type != "simple") &&
				    (CandyDemo.instance.level.GetCandy()[i].GetComponent<CandyController>().GetNeighbor(direction[j]) != null)){
					if (CandyDemo.instance.level.GetCandy()[i].GetComponent<CandyController>().GetNeighbor(direction[j]).GetComponent<CandyController>().Type != "simple"){
                        CandyDemo.instance.suggest_item1 = CandyDemo.instance.level.GetCandy()[i];
						CandyDemo.instance.suggest_item2 = CandyDemo.instance.level.GetCandy()[i].GetComponent<CandyController>().GetNeighbor(direction[j]);
						manager.Direction=CandyDemo.instance.suggest_item1.GetComponent<CandyController>().GetDirectionNeighbor(CandyDemo.instance.suggest_item2);
                    	CandyDemo.instance.Hint();
						manager.gamestate=GameState.playing;
						return;
                    }
                }
            }
			if (CandyDemo.instance.level.GetCandy()[i].GetComponent<CandyController>().Type == "star"){
                CandyDemo.instance.suggest_item1 = CandyDemo.instance.level.GetCandy()[i];
            A:
					CandyDemo.instance.suggest_item2 = CandyDemo.instance.level.GetCandy()[i].GetComponent<CandyController>().GetNeighbor(direction[Random.Range(0, direction.Length)]);
                if (CandyDemo.instance.suggest_item2 == null) { goto A; }
				manager.Direction=CandyDemo.instance.suggest_item1.GetComponent<CandyController>().GetDirectionNeighbor(CandyDemo.instance.suggest_item2);
				CandyDemo.instance.Hint();
				manager.gamestate=GameState.playing;
				return;
            }
        }
		manager.gamestate=GameState.nomorematch;
        no_more.SetActive(true);
        manager.NoMove = true;
		CancelInvoke();	
    }
	private string[] neighbor={"up","down","left","right"};
	private GameObject temp;
	private Vector3 tmp;
	public void NoMoreMatch(){	
		if(manager.gamestate!=GameState.nomorematch){return;}
		manager.gamestate=GameState.nomorematch;
		manager.NoMove=false;
		Suffle();
	}
	private void Suffle(){
		if(manager.gamestate!=GameState.nomorematch){return;}
		for(int i=0;i<CandyDemo .instance.level.GetCandy().Length;i++){
			if(CandyDemo.instance.level.GetCandy()[i].GetComponent<CandyController>().Type!="simple"){
				continue;
			}
			tmp=CandyDemo.instance.level.GetCandy()[i].transform.position;
			temp=CandyDemo.instance.level.GetCandy()[i].GetComponent<CandyController>().GetNeighbor(neighbor[Random.Range(0,neighbor.Length)]);
			if(temp==null){
				continue;
			}else if(temp.GetComponent<CandyController>().Type!="simple"){
				continue;
			}
			CandyDemo.instance.level.GetCandy()[i].transform.position=temp.transform.position;
			temp.transform.position=tmp;
			temp=null;
		}
		CandyDrop.instance.KinematicCandy(true);
		no_more.SetActive(false);
		CancelInvoke();
		Invoke("SetKinematicCandy",0.5f);
		manager.gamestate=GameState.checkaterdrop;
		Invoke("CheckAfterDrop",1f);
	}
	private void SetKinematicCandy(){
		CandyDrop.instance.KinematicCandy(false);
	}
    string n_color = "", obj_color = "";
    public bool TestWithNeighbor(GameObject obj, string dir){
		if (obj.GetComponent<CandyController>().GetNeighbor(dir) == null) { return false; }
		obj_color = obj.GetComponent<CandyController>().Candy_Color;
		n_color = obj.GetComponent<CandyController>().GetNeighbor(dir).GetComponent<CandyController>().Candy_Color;
		obj.GetComponent<CandyController>().GetNeighbor(dir).GetComponent<CandyController>().Candy_Color = obj.GetComponent<CandyController>().Candy_Color;
		obj.GetComponent<CandyController>().Candy_Color = n_color;
		if (TestMatch(obj.GetComponent<CandyController>().GetNeighbor(dir))){
			obj.GetComponent<CandyController>().GetNeighbor(dir).GetComponent<CandyController>().Candy_Color = n_color;
			obj.GetComponent<CandyController>().Candy_Color = obj_color;
            return true;
        }
		obj.GetComponent<CandyController>().GetNeighbor(dir).GetComponent<CandyController>().Candy_Color = n_color;
		obj.GetComponent<CandyController>().Candy_Color = obj_color;
        return false;
    }
    private bool TestMatch(GameObject obj)
    {
        if (obj == null) { return false; }
        CheckHorizontalAndVertical(obj);
        if ((h_list.Count>=3) || (v_list.Count>=3))
        {
            return true;
        }
        return false;
    }
    public void CheckHorizontalAndVertical(GameObject obj){
        h_list.Clear(); v_list.Clear();
        v_list.Add(obj); h_list.Add(obj);
		CheckVH(obj, "up", ref v_list);
		CheckVH(obj, "down", ref v_list);
		CheckVH(obj, "right", ref h_list);
		CheckVH(obj, "left", ref h_list);
    }
    public void Checking(GameObject obj){	
		if (obj.GetComponent<CandyController>().check){
            return;
        }
        CheckHorizontalAndVertical(obj);
        if (v_list.Count >= 5) {
            manager.IsMatch = true;
            special_matched_candy_count += v_list.Count;
            Match.instance.SetMatchedCandy(v_list, obj, "star", false);
            return;
        }
        if (h_list.Count >= 5){
            manager.IsMatch = true;
            special_matched_candy_count += h_list.Count;
            Match.instance.SetMatchedCandy(h_list, obj, "star", false);
            return;
        }
        if ((v_list.Count > 2) && (h_list.Count <= 2)){
            manager.IsMatch = true;
            switch (v_list.Count){
			case 3:manager.IsMatch = true;
                    simple_matched_candy_count += v_list.Count;
                    Match.instance.SetMatchedCandy(v_list, null, "simple", true);
                    break;
			case 4:manager.IsMatch = true;
                    special_matched_candy_count += v_list.Count;
				if (obj.GetComponent<CandyController>().Type != "simple")
                    {
                        obj = GetOtherCandyToKeep(obj, v_list);
                    }
                    Match.instance.SetMatchedCandy(v_list, obj, "horizontal", false);
                    break;
            }
        }
        else if ((v_list.Count <= 2) && (h_list.Count > 2)){
            manager.IsMatch = true;
            switch (h_list.Count){
                case 3:simple_matched_candy_count += h_list.Count;
                    Match.instance.SetMatchedCandy(h_list, null, "simple", true);
                    break;
                case 4:special_matched_candy_count += h_list.Count;
				if (obj.GetComponent<CandyController>().Type != "simple"){
                        obj = GetOtherCandyToKeep(obj, h_list);
                    }
                    Match.instance.SetMatchedCandy(h_list, obj, "vertical", false);
                    break;
            }
        }
        else if ((v_list.Count > 2) && (h_list.Count > 2)) {
            manager.IsMatch = true;
            foreach (GameObject cc in v_list) {
				cc.GetComponent<CandyController>().IsMatched = true;
				cc.GetComponent<CandyController>().check = true;
                special_matched_candy_count += 1;
            }
            foreach (GameObject cc in h_list){
				cc.GetComponent<CandyController>().IsMatched = true;
				cc.GetComponent<CandyController>().check = true;
                special_matched_candy_count += 1;
            }
			obj.GetComponent<CandyController>().check = true;
			obj.GetComponent<CandyController>().IsMatched = false;
			if (obj.GetComponent<CandyController>().Type != "simple") {
                obj = GetOtherCandyToKeep(obj, v_list);
            }
            Match.instance.ChangeType(obj, "special");
        }
    }
    private GameObject GetOtherCandyToKeep(GameObject obj, List<GameObject> list){
        int i;
        for (i = 0; i < list.Count; i++){
            if (list[i] == obj){
                break;
			}
        }
        if (i < list.Count - 1) {
            return list[i + 1];
        }
        else{
            return list[i - 1];
        }
    }
    public void CheckAllObject(){	
        for (int j = 0; j < CandyDemo.instance.level.GetCandy().Length;j++){
			Checking(CandyDemo.instance.level.GetCandy()[j]);
        }
    }
    public int special_matched_candy_count, simple_matched_candy_count;
    public void CheckAfterDrop(){
		if(manager.gamestate!=GameState.checkaterdrop){return;}
		CancelInvoke();
		no_more.SetActive(false);
		manager.NoMove=false;
        CheckAllObject();
        CandyDemo.instance.UIscore.AddScore((special_matched_candy_count  ) * 40);
        CandyDemo.instance.UIscore.AddScore((simple_matched_candy_count ) * 20);
        special_matched_candy_count = simple_matched_candy_count = 0;
        foreach (GameObject cs in CandyDemo.instance.level.GetCandy()){
			cs.GetComponent<CandyController>().is_fall_down = false;
			cs.GetComponent<CandyController>().check=false;
        }
        if (manager.IsMatch) {
			manager.gamestate=GameState.destroy;
            CandyDrop.instance.DroppingCandy();
            return;
        }
        else{
            if (CandyDemo.instance.move_number == 0){
                if (CandyDemo.instance.UIscore.GetScore() >= CandyDemo.instance.target){
                    if (manager.Sound) { 
						SoundCon.instance.PlaySound(11); 
					}
                    if (manager.currentLevel == 10){
                        CandyDemo.instance.objRetry[2].GetComponent<tk2dTextMesh>().text = "Congratulation";
						playerScoreR.GetComponent<tk2dTextMesh>().text="Win";
						manager.gamestate=GameState.lose;
                        CandyDemo.instance.retry.Action();
					}
                    else{
                        if (!sugar_crush){
                            sugarCrush.SetActive(true);
                            sugar_crush = true;
							Invoke("DisableSugarCrush", 2f);
							Invoke("CheckSpecial", 2.1f);
						}else{
							CheckSpecial();
						}
                    }  
                }
                else {
                    CandyDemo.instance.retry.Action();
                    playerScoreR.text = "Need " + (CandyDemo.instance.target - CandyDemo.instance.UIscore.GetScore()).
                            ToString() + " \n Score More";
					manager.gamestate=GameState.lose;
                }
                return;
            }
        }
		manager.gamestate=GameState.checkboardstate;
        Invoke("CheckBoardState",0.1f);
    }
    private bool ClearSpecialCandy() {
        for (int i = 0; i < CandyDemo.instance.level.GetCandy().Length; i++) {
			if (CandyDemo.instance.level.GetCandy()[i].GetComponent<CandyController>().Type != "simple"){
				CandyDemo.instance.level.GetCandy()[i].GetComponent<CandyController>().IsMatched = true;
				manager.gamestate=GameState.destroy;
                CandyDrop.instance.DroppingCandy();
				return true;
            }
        }
		return false;
    }
    private void LoadNext(){
        CandyDemo.instance.next.Action();
        if ((manager.lastLevel == manager.currentLevel)&&(manager.lastLevel<=10)) {
            manager.lastLevel += 1;
            PlayerPrefs.SetInt("lastlevel", manager.lastLevel);
        }
        manager.currentLevel += 1;
    }
    private void CheckSpecial(){
        if (ClearSpecialCandy()){
            return;
        }
		playerScoreR.text = playerScoreN.text = "Your Score: \n" + CandyDemo.instance.UIscore.GetScore().ToString();
		PlayerPrefs.SetInt(manager.currentLevel.ToString(), CandyDemo.instance.UIscore.GetScore());
		Invoke("LoadNext", 0.5f);
        playerScoreN.text = "Your Score: \n" + CandyDemo.instance.UIscore.GetScore().ToString();
		manager.gamestate=GameState.win;
    }
    private void DisableSugarCrush(){
        sugarCrush.SetActive(false);
    }
    private void CompleteAllLevels() { 
		levelCompete.SetActive(false); 
	}
	private bool CheckVH(GameObject obj, string dir, ref List<GameObject> list) {
		count++;
		if ((obj.GetComponent<CandyController>().GetNeighbor(dir) == null)) { return false; }
		if(CheckNextTo(obj,obj.GetComponent<CandyController>().GetNeighbor(dir))){
			list.Add(obj.GetComponent<CandyController>().GetNeighbor(dir));
			return CheckVH(obj.GetComponent<CandyController>().GetNeighbor(dir), dir, ref list);
		}
		return false;
	}
    public bool CheckNextTo(GameObject obj, GameObject next_to) {
        if ((next_to == null) || (obj == null)) return false;
		return obj.GetComponent<CandyController>().Candy_Color == next_to.GetComponent<CandyController>().Candy_Color;
    }

}
